/*
 * regionSelection.js
 * 
 * A collection of functions to handle the selection of regions for which to view data
 * 
 * AUTHORS
 * 	Preben Ingvaldsen
 *  Stan Peck
 */

/*
 * selectRegion
 * 
 * Performs the region selection operation by centering the map on the user-input region
 * and filtering the data to only display a summary for entries from the input region
 */
cs441ShibeDoge.selectRegion = function() {
	var newDataSet = cs441ShibeDoge.data;
	var oldRows = cs441ShibeDoge.allApplicantRows;
	var newRows = new Array();
	var city = document.getElementById("city").value;
	var state = document.getElementById("state").value;

	cs441ShibeDoge.dataObject.REGION_TYPE = cs441ShibeDoge.CITY_SELECTED;

	//Remove any data not in the selected region
	for (var i = 0; i < oldRows.length; i++) {
		if (oldRows[i][14] == city && oldRows[i][15] == state) {
			newRows.push(oldRows[i]);
		}
	}
	newDataSet.rows = newRows;

	//Update the table accordingly
	cs441ShibeDoge.calculateDataFields(newDataSet);
	cs441ShibeDoge.currentDataSet = newDataSet;
	cs441ShibeDoge.currentCityDataSet = cs441ShibeDoge.currentDataSet.rows.slice(0);

	//Update the table title
	document.getElementById("tablesTitle").innerHTML = "Summary data for all " + city + ", " + state + " applicants";	

	//Show the "show all applicants" button
	document.getElementById("showAll").style.display = 'block';

	//Center the map on the selected city
	cs441ShibeDoge.geocodeCenter(city + ", " + state, 10);

	//Pull out the unique CEEB codes for the selected region
	var ceebCodes = new Array();
	var currentCEEB;
	for (var i = 0; i < newDataSet.rows.length; i++) {
		currentCEEB = newDataSet.rows[i][2];
		if (ceebCodes.indexOf(currentCEEB) == -1) {
			ceebCodes.push(currentCEEB);
		}
	}
	
	//Disable the UI Elements until such time as the geocoding is complete
	document.getElementById("state").disabled = true;
	document.getElementById("city").disabled = true;
	document.getElementById("regionSelectButton").disabled = true;
	document.getElementById("showAllButton").disabled = true;
	document.getElementById("loadingRegionMessage").style.display = "block";

	//Store the CEEB Codes for the selected region for later use
	cs441ShibeDoge.currentRegionCEEBCodes = ceebCodes;
	cs441ShibeDoge.currentlySelectedCity = city;
	if (cs441ShibeDoge.currentlySelectedState == undefined || cs441ShibeDoge.currentlySelectedState != state) {
		cs441ShibeDoge.currentlySelectedState = state;
		cs441ShibeDoge.scrapeHighSchoolNames(state);
	}
	else {
		cs441ShibeDoge.currentRegionHighSchoolLatLng = new Array();
		cs441ShibeDoge.currentRegionHighSchoolNames = new Array();
		cs441ShibeDoge.findCurrentRegionHighSchools(cs441ShibeDoge.currentStateHighSchools);
	}

}

/*
 * populateStateSelectDropDown
 * 
 * Populates the state select dropdown
 */
cs441ShibeDoge.populateStateSelectDropDown = function(data) {
	var currEntryCity;
	var currEntryState;

	//Stores data to help us parse the dropdown menus, such as whether or not
	//a city/state has previously been seen and lists of cities in a particular
	//state
	var dropDownEntryStorage = {};
	dropDownEntryStorage.stateList = ["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL",
	                                  "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME",
	                                  "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH",
	                                  "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI",
	                                  "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"];

	//Initialize the city lists
	for (var i = 0; i < dropDownEntryStorage.stateList.length; i++) {
		dropDownEntryStorage[dropDownEntryStorage.stateList[i] + "_CITIES"] = new Array();
	}

	for (var row = 0; row < data.rows.length; row++) {
		currEntryCity = data.rows[row][14];
		currEntryState = data.rows[row][15];

		if (currEntryCity == "" || dropDownEntryStorage.stateList.indexOf(currEntryState) == -1) {
			continue;
		}

		if (dropDownEntryStorage[currEntryState + "_CITIES"].indexOf(currEntryCity) == -1) {
			dropDownEntryStorage[currEntryState + "_CITIES"].push(currEntryCity);
		}
	}

	//Parse the options into an HTML string and write it to the document
	var dropDownOptions = "<option value='all'>Show Data for All States</option>\n";
	for (var i = 0; i < dropDownEntryStorage.stateList.length; i++) {
		dropDownOptions += "<option value='" + dropDownEntryStorage.stateList[i] + "'>" + dropDownEntryStorage.stateList[i] + "</option>\n";
	}
	document.getElementById("state").innerHTML = dropDownOptions;

	//Cache the data for later use
	cs441ShibeDoge.dropDownData = dropDownEntryStorage;
	stateList = ["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL",
	             "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME",
	             "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH",
	             "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI",
	             "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"]
}

/*
 * updateCityDropdown
 * 
 * Updates the city dropdown menu based on what was selected in the selectState
 * dropdown
 */
cs441ShibeDoge.updateCityDropdown = function() {
	var selectedState = document.getElementById("state").value;
	var cityDropDown = document.getElementById("city");

	//Hide the dropdown if no state is selected
	if (selectedState == "all") {
		document.getElementById('citySelect').style.display = "none";
	}

	//Otherwise, update the city dropdown with the list of cities in that state for which
	//we have data and display it
	else {
		var cityList = cs441ShibeDoge.dropDownData[selectedState + "_CITIES"];
		cityList.sort();
		var dropDownOptions = "<option value='all'>Select a City</option>\n";
		for (var i = 0; i < cityList.length; i++) {
			dropDownOptions += "<option value='" + cityList[i] + "'>" + cityList[i] + "</option>\n";
		}
		cityDropDown.innerHTML = dropDownOptions;
		document.getElementById('citySelect').style.display = "block";
	}
}

/*
 * displayRegionSelectSubmitButton
 * 
 * Displays the region select submit button based on the option selected in the city select dropdown
 * 
 */
cs441ShibeDoge.displayRegionSelectSubmitButton = function() {
	var selectedCity = document.getElementById("city").value;

	if (selectedCity == "all") {
		document.getElementById("regionSelectButton").style.display = "none";
	}
	else {
		document.getElementById("regionSelectButton").style.display = "inline-block";
	}
}

/*
 * deselectAndShowAllApplicants
 * 
 * Deselects the currently selected region, if any, and displays data for all applicants
 */
cs441ShibeDoge.deselectAndShowAllApplicants = function() {
	if(typeof cs441ShibeDoge.markerList != 'undefined'){
		for(var x = 0; x < cs441ShibeDoge.markerList.length; x++){
			cs441ShibeDoge.markerList[x].setMap(null);
		}
		cs441ShibeDoge.markerList = new Array();
	}
	else{
		cs441ShibeDoge.markerList = new Array();
	}
	
	if (cs441ShibeDoge.dataObject.REGION_TYPE != cs441ShibeDoge.NO_REGION_SELECTED) {
		document.getElementById("city").value = 'all';
		var state = document.getElementById("state").value = 'all';
		document.getElementById("regionSelectButton").style.display = "none";
		document.getElementById('citySelect').style.display = "none";

		cs441ShibeDoge.dataObject.REGION_TYPE = cs441ShibeDoge.NO_REGION_SELECTED;
		cs441ShibeDoge.data.rows = cs441ShibeDoge.allApplicantRows;

		cs441ShibeDoge.calculateDataFields(cs441ShibeDoge.data);
		cs441ShibeDoge.currentDataSet = cs441ShibeDoge.data;

		//Update the table title
		document.getElementById("tablesTitle").innerHTML = "Summary Data for All United States applicants";

		//Hide the "Show Data for All Applicants" button
		document.getElementById("showAll").style.display = 'none';
		
		//see if you can get this to toggle
		document.getElementById("filterSelectButton").style.display = 'inline-block';

		//Zoom out and center the map on the United States
		cs441ShibeDoge.geocodeCenter("United States", 4);
//		cs441ShibeDoge.layer.setMap(null);
	}
}

/*
 * parseHighSchools
 * 
 * Takes the names of the various high schools in the given city, parses them, 
 * then filters out any high schools not in our current region
 */
cs441ShibeDoge.parseHighSchools = function(data) {
	if (request.readyState === 4){
		if(request.status === 200){
			//Translate our response into something we can mess with
			data = JSON.parse(request.responseText);
			cs441ShibeDoge.currentStateHighSchools = data;
			cs441ShibeDoge.findCurrentRegionHighSchools(data);
		}
	}
}

/*
 * findCurrentRegionHighSchools
 * 
 * Takes a list of high schools in a given state and pulls out the names of those we have data for in
 * the currently selected region. Then, finds the latitudes and longitudes of each of the high schools
 * in the currently selected region.
 */
cs441ShibeDoge.findCurrentRegionHighSchools = function(data) {
	var currRegionCEEBs = cs441ShibeDoge.currentRegionCEEBCodes;
	var highSchools = data.rows;
	var currentRegionSchools = new Array();

	//Get the names of high schools for which we have data in the current region
	for (var i = 0; i < highSchools.length; i++) {
		if (currRegionCEEBs.indexOf(highSchools[i][1]) != -1) {
			currentRegionSchools.push(highSchools[i][0]);
		}
	}
	cs441ShibeDoge.currentRegionHighSchoolLatLng = new Array();
	cs441ShibeDoge.currentRegionHighSchoolNames = new Array();
	cs441ShibeDoge.geocodeHighSchools(currentRegionSchools, 0);
}

/*
 * geocodeHighSchools
 * 
 * Takes a list of high school names and geocodes them, finding the latitude and longitude of
 * each high school
 */
cs441ShibeDoge.geocodeHighSchools = function(highSchoolNames, i) {
	var city = cs441ShibeDoge.currentlySelectedCity;
	var state = cs441ShibeDoge.currentlySelectedState;
	cs441ShibeDoge.numHighSchoolsInRegion = highSchoolNames.length;
	var stringToGeocode;
	if (cs441ShibeDoge[city + ", " + state] != undefined) {
		//TODO: put the cached city/state data into cs441ShibeDoge
		cs441ShibeDoge.currentRegionHighSchoolLatLng = cs441ShibeDoge[city + ", " + state].slice(0);
		cs441ShibeDoge.currentRegionHighSchoolNames = cs441ShibeDoge[city + ", " + state + "_NAMES"].slice(0);

		if(typeof cs441ShibeDoge.markerList != 'undefined'){
			for(var x = 0; x < cs441ShibeDoge.markerList.length; x++){
				cs441ShibeDoge.markerList[x].setMap(null);
			}
			cs441ShibeDoge.markerList = new Array();
		}
		else{
			cs441ShibeDoge.markerList = new Array();
		}
		for (var x = 0; x < cs441ShibeDoge.currentRegionHighSchoolLatLng.length; x++){
			var marker = new google.maps.Marker({
				position: cs441ShibeDoge.currentRegionHighSchoolLatLng[x],
				animation: google.maps.Animation.DROP,
				map: cs441ShibeDoge.map,
				title: cs441ShibeDoge.currentRegionHighSchoolNames[x]
			 });
			cs441ShibeDoge.markerList.push(marker);
		}
		for(var x = 0; x < cs441ShibeDoge.markerList.length; x++){
			google.maps.event.addListener(cs441ShibeDoge.markerList[x], 'click', function() {
				request = new XMLHttpRequest();
				cs441ShibeDoge.hsName = this.title; 
				url = "https://www.googleapis.com/fusiontables/v1/query?sql=SELECT * FROM 1SInAG971GTVrZOVqt0ORpMDPWYAb5DjoWpPCnRg WHERE 'High School Name'='" + this.title + "'&key="
				url = url + "AIzaSyDkeXsopORSm1LWznQIgrUn0Z2h768EWqs";

				request.onreadystatechange = function(data){
					//Make sure everything went according to plan
					if (request.readyState === 4){
						if(request.status === 200){
							//Translate our response into something we can mess with
							data = JSON.parse(request.responseText);
							for(var y = 0; y < data.rows.length; y++){
								if (data.rows[y][2] == cs441ShibeDoge.currentlySelectedState){
									cs441ShibeDoge.currentlySelectedSchool = data.rows[y][1];
								}
							}
							var newDataSet = cs441ShibeDoge.currentDataSet;
							var oldRows = cs441ShibeDoge.currentCityDataSet;
							var newRows = new Array();
							//Remove any data not in the selected region
							for (var i = 0; i < oldRows.length; i++) {
								if (oldRows[i][2] == cs441ShibeDoge.currentlySelectedSchool) {
									newRows.push(oldRows[i]);
								}
							}
							newDataSet.rows = newRows;
							cs441ShibeDoge.calculateDataFields(newDataSet);
							cs441ShibeDoge.currentDataSet = newDataSet;
							document.getElementById("tablesTitle").innerHTML = "Summary data for " + cs441ShibeDoge.hsName;
						}
					}
				};
				request.open('GET', url);
				request.send();						
			});
		}

		document.getElementById("state").disabled = false;
		document.getElementById("city").disabled = false;
		document.getElementById("regionSelectButton").disabled = false;
		document.getElementById("showAllButton").disabled = false;
		document.getElementById("loadingRegionMessage").style.display = "none";
		return;
	}
	//Geocode the names of the various high schools and push their coordinates onto an array

	stringToGeocode = highSchoolNames[i] + ", " + state;
	cs441ShibeDoge.geocoder.geocode({
		'address' : stringToGeocode
	}, function(results, status) {
		if(status == google.maps.GeocoderStatus.OK) {
			var address = results[0].formatted_address.split(",");
			var inCity = false;
			for (var j = 0; j < address.length; j++) {
				if (address[j].trim() == cs441ShibeDoge.currentlySelectedCity) {
					inCity = true;
				}
			}
			if (inCity) {
				cs441ShibeDoge.currentRegionHighSchoolLatLng.push(results[0].geometry.location);
				cs441ShibeDoge.currentRegionHighSchoolNames.push(address[0]);
			}
			if (i == highSchoolNames.length - 1) {
				//Cache the data to reduce the number of required geocoding requests since we have a limit of 2500
				cs441ShibeDoge[cs441ShibeDoge.currentlySelectedCity + ", " + cs441ShibeDoge.currentlySelectedState] = cs441ShibeDoge.currentRegionHighSchoolLatLng.slice(0);
				cs441ShibeDoge[cs441ShibeDoge.currentlySelectedCity + ", " + cs441ShibeDoge.currentlySelectedState + "_NAMES"] = cs441ShibeDoge.currentRegionHighSchoolNames.slice(0);
				//Do stuff with markers
				if(typeof cs441ShibeDoge.markerList != 'undefined'){
					for(var x = 0; x < cs441ShibeDoge.markerList.length; x++){
						cs441ShibeDoge.markerList[x].setMap(null);
					}
					cs441ShibeDoge.markerList = new Array();
				}
				else{
					cs441ShibeDoge.markerList = new Array();
				}
				for (var x = 0; x < cs441ShibeDoge.currentRegionHighSchoolLatLng.length; x++){
					var marker = new google.maps.Marker({
						position: cs441ShibeDoge.currentRegionHighSchoolLatLng[x],
						animation: google.maps.Animation.DROP,
						map: cs441ShibeDoge.map,
						title: cs441ShibeDoge.currentRegionHighSchoolNames[x]
					 });
					cs441ShibeDoge.markerList.push(marker);
				}
				for(var x = 0; x < cs441ShibeDoge.markerList.length; x++){
					google.maps.event.addListener(cs441ShibeDoge.markerList[x], 'click', function() {
						request = new XMLHttpRequest();
						cs441ShibeDoge.hsName = this.title; 
						url = "https://www.googleapis.com/fusiontables/v1/query?sql=SELECT * FROM 1SInAG971GTVrZOVqt0ORpMDPWYAb5DjoWpPCnRg WHERE 'High School Name'='" + this.title + "'&key="
						url = url + "AIzaSyDkeXsopORSm1LWznQIgrUn0Z2h768EWqs";

						request.onreadystatechange = function(data){
							//Make sure everything went according to plan
							if (request.readyState === 4){
								if(request.status === 200){
									//Translate our response into something we can mess with
									data = JSON.parse(request.responseText);
									for(var y = 0; y < data.rows.length; y++){
										if (data.rows[y][2] == cs441ShibeDoge.currentlySelectedState){
											cs441ShibeDoge.currentlySelectedSchool = data.rows[y][1];
										}
									}
									var newDataSet = cs441ShibeDoge.currentDataSet;
									var oldRows = cs441ShibeDoge.currentCityDataSet;
									var newRows = new Array();
									//Remove any data not in the selected region
									for (var i = 0; i < oldRows.length; i++) {
										if (oldRows[i][2] == cs441ShibeDoge.currentlySelectedSchool) {
											newRows.push(oldRows[i]);
										}
									}
									newDataSet.rows = newRows;
									cs441ShibeDoge.calculateDataFields(newDataSet);
									cs441ShibeDoge.currentDataSet = newDataSet;
									document.getElementById("tablesTitle").innerHTML = "Summary data for " + cs441ShibeDoge.hsName;
								}
							}
						};
						request.open('GET', url);
						request.send();						
					});
				}
				
				//Re-enable our UI elements
				document.getElementById("state").disabled = false;
				document.getElementById("city").disabled = false;
				document.getElementById("regionSelectButton").disabled = false;
				document.getElementById("showAllButton").disabled = false;
				document.getElementById("loadingRegionMessage").style.display = "none";
				
			}
			else {
				cs441ShibeDoge.geocodeHighSchools(highSchoolNames, i+1);
			}
		} 
		else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {    
            setTimeout(function() {
                cs441ShibeDoge.geocodeHighSchools(highSchoolNames, i);
            }, 200);
		}
		else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
			if (i == highSchoolNames.length - 1) {
				//Re-enable our UI elements
				document.getElementById("state").disabled = false;
				document.getElementById("city").disabled = false;
				document.getElementById("showAllButton").disabled = true;
				document.getElementById("regionSelectButton").disabled = false;
				document.getElementById("loadingRegionMessage").style.display = "none";
			}
			else {
				cs441ShibeDoge.geocodeHighSchools(highSchoolNames, i+1);
			}
		}
		else {
			console.log("Geocode was not successful for the following reason: " + status);
		}
	});
}

/*
 * geocodeCenter
 * 
 * Geocodes a given string and sets the center of the map to the returned
 * latitude and longitude at the given zoom level
 */
cs441ShibeDoge.geocodeCenter = function(stringToGeocode, zoom) {
	cs441ShibeDoge.geocoder.geocode({
		'address' : stringToGeocode
	}, function(results, status) {
		if(status == google.maps.GeocoderStatus.OK) {
			cs441ShibeDoge.map.setCenter(results[0].geometry.location);
			cs441ShibeDoge.map.setZoom(zoom);
		} 
		else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
			setTimeout(function() {cs441ShibeDoge.geocodeCenter(stringToGeocode, zoom);}, 200);
		}
		else {
			alert("Geocode was not successful for the following reason: " + status);
		}
	});
}
